#include <stdio.h>
#include <stdlib.h>

#define M 3
#define N 4

int** matMul(int m, int n, int (*mat1)[], int (*mat2)[]);
void printMat(int m, int n, int (*mat)[]);
void printMat2(int m, int n, int **pmat);

int main()
{
    int mat1[M][N] = {{1,6,4,9},{2,3,7,10},{3,6,7,5}};
    int mat2[N][M] = {{2,8,0},{1,5,7},{3,3,6},{4,1,0}};

    printMat(M, N, mat1);
    printf("---------------\n");
    printMat(N, M, mat2);

    int **result = NULL;

    result = matMul(M, N, mat1, mat2);
    
    printf("--------------------\n");

    printMat2(M, M, result); 

    for (int i = 0; i < M; i ++)
    {
        free(result[i]);
        result[i] = NULL;
    }

    free(result);
    result = NULL;

    return 0;
}

void printMat(int m, int n, int (*mat)[n])
{
    for (int i = 0; i < m; i ++)
    {
        for (int j = 0; j < n; j ++)
        {
            printf("%5d\t", mat[i][j]);
        }
        printf("\n");
    }
}

void printMat2(int m, int n, int **pmat)
{
    for (int i = 0; i < m; i ++)
    {
        for (int j = 0; j < n; j ++)
        {
            printf("%5d\t", pmat[i][j]);
        }
        printf("\n");
    }
}

int** matMul(int m, int n, int (*mat1)[n], int (*mat2)[m])
{
    int **result = NULL;

    result = (int**)malloc(sizeof(int *) * m);

    if (NULL != result)
    {
        for (int i = 0; i < m; i ++)
        {
            result[i] = (int*)malloc(sizeof(int) * m);
            for (int j = 0; j < m; j ++)
            {
                // the r-th row of mat1, and the c-th column of mat2
                int temp = 0;
                for (int r = 0; r < n; r ++)
                {
                    temp += mat1[i][r] * mat2[r][j];
                }
                result[i][j] = temp;
            }

        }
        return result;
    }
    else
    {
        return NULL;
    }
}



